#pragma once
#include <string>

/**
    Joystick buttons

    NOTE: Right now we only support the Xbox360 controller
 */
enum JoystickButtons_t
{
    J_UNKNOWN,

    J_A,
    J_B,
    J_X,
    J_Y,

    J_LEFT_TRIGGER,
    J_RIGHT_TRIGGER,

    J_BACK,
    J_START,

    J_LEFT_JOYSTICK,
    J_RIGHT_JOYSTICK
};

/**
    Mouse Buttons
  
*/
enum MouseButtons_t 
{
    MMB_UNKNOWN     = 0,
    MMB_BUTTON1     = 1,
    MMB_BUTTON2     = 2,
    MMB_BUTTON3     = 4,

    MMB_WHEELUP     = 5,
    MMB_WHEELDOWN   = 6
};


/** 
    Keyboard buttons

*/
enum KeyboardButtons_t
{
	MK_UNKNOWN      = 0,
	MK_BACKSPACE	= 8,
	MK_TAB		    = 9,
	MK_CLEAR		= 12,
	MK_RETURN		= 13,
	MK_PAUSE		= 19,
	MK_ESCAPE		= 27,
	MK_SPACE		= 32,
	MK_EXCLAIM	    = 33,
	MK_QUOTEDBL	    = 34,
	MK_HASH		    = 35,
	MK_DOLLAR		= 36,
    MK_PERCENT      = 37,
	MK_AMPERSAND	= 38,
	MK_QUOTE		= 39,
	MK_LEFTPAREN	= 40,
	MK_RIGHTPAREN	= 41,
	MK_ASTERISK	    = 42,
	MK_PLUS		    = 43,
	MK_COMMA		= 44,
	MK_MINUS		= 45,
	MK_PERIOD		= 46,
	MK_SLASH		= 47,
	MK_0			= 48,
	MK_1			= 49,
	MK_2			= 50,
	MK_3			= 51,
	MK_4			= 52,
	MK_5			= 53,
	MK_6			= 54,
	MK_7			= 55,
	MK_8			= 56,
	MK_9			= 57,
	MK_COLON		= 58,
	MK_SEMICOLON	= 59,
	MK_LESS		    = 60,
	MK_EQUALS		= 61,
	MK_GREATER	    = 62,
	MK_QUESTION	    = 63,
	MK_AT			= 64,
	/* 
	   Skip uppercase letters
	 */
	MK_LEFTBRACKET	= 91,
	MK_BACKSLASH	= 92,
	MK_RIGHTBRACKET	= 93,
	MK_CARET		= 94,
	MK_UNDERSCORE	= 95,
	MK_BACKQUOTE	= 96,
	MK_a			= 97,
	MK_b			= 98,
	MK_c			= 99,
	MK_d			= 100,
	MK_e			= 101,
	MK_f			= 102,
	MK_g			= 103,
	MK_h			= 104,
	MK_i			= 105,
	MK_j			= 106,
	MK_k			= 107,
	MK_l			= 108,
	MK_m			= 109,
	MK_n			= 110,
	MK_o			= 111,
	MK_p			= 112,
	MK_q			= 113,
	MK_r			= 114,
	MK_s			= 115,
	MK_t			= 116,
	MK_u			= 117,
	MK_v			= 118,
	MK_w			= 119,
	MK_x			= 120,
	MK_y			= 121,
	MK_z			= 122,
    MK_PIPE         = 124,
	MK_DELETE		= 127,
	/* End of ASCII mapped keysyms */

	/* Numeric keypad */
	MK_KP0		= 256,
	MK_KP1		= 257,
	MK_KP2		= 258,
	MK_KP3		= 259,
	MK_KP4		= 260,
	MK_KP5		= 261,
	MK_KP6		= 262,
	MK_KP7		= 263,
	MK_KP8		= 264,
	MK_KP9		= 265,
	MK_KP_PERIOD	= 266,
	MK_KP_DIVIDE	= 267,
	MK_KP_MULTIPLY	= 268,
	MK_KP_MINUS		= 269,
	MK_KP_PLUS		= 270,
	MK_KP_ENTER		= 271,
	MK_KP_EQUALS	= 272,

	/* Arrows + Home/End pad */
	MK_UP		= 273,
	MK_DOWN		= 274,
	MK_RIGHT	= 275,
	MK_LEFT		= 276,
	MK_INSERT	= 277,
	MK_HOME		= 278,
	MK_END		= 279,
	MK_PAGEUP	= 280,
	MK_PAGEDOWN	= 281,

	/* Function keys */
	MK_F1		= 282,
	MK_F2		= 283,
	MK_F3		= 284,
	MK_F4		= 285,
	MK_F5		= 286,
	MK_F6		= 287,
	MK_F7		= 288,
	MK_F8		= 289,
	MK_F9		= 290,
	MK_F10		= 291,
	MK_F11		= 292,
	MK_F12		= 293,
	MK_F13		= 294,
	MK_F14		= 295,
	MK_F15		= 296,

	/* Key state modifier keys */
	MK_NUMLOCK	= 300,
	MK_CAPSLOCK	= 301,
	MK_SCROLLOCK= 302,
	MK_RSHIFT	= 303,
	MK_LSHIFT	= 304,
	MK_RCTRL	= 305,
	MK_LCTRL	= 306,
	MK_RALT		= 307,
	MK_LALT		= 308,
	MK_RMETA	= 309,
	MK_LMETA	= 310,
	MK_LSUPER	= 311,		    /* Left "Windows" key */
	MK_RSUPER	= 312,		    /* Right "Windows" key */
	MK_MODE		= 313,		    /* "Alt Gr" key */
	MK_COMPOSE	= 314,		/* Multi-key compose key */

	/* Miscellaneous function keys */
	MK_HELP		= 315,
	MK_PRINT	= 316,
	MK_SYSREQ	= 317,
	MK_BREAK	= 318,
	MK_MENU		= 319,
	MK_POWER	= 320,		/* Power Macintosh power key */
	MK_EURO		= 321,		/* Some european keyboards */
	MK_UNDO		= 322,		/* Atari keyboard has Undo */

	/* Add any other keys here */

	MK_LAST    
};


/**
========================
Converts key codes to a string and also converts strings to key codes
========================
*/
class KeyConverter
{
public:
    KeyConverter(void);
    
    /** Converts the given key to a string (Ex. SDLK_BACKSPACE would equal "backspace")
    */
    std::string ToString( int key ) const;

    /** Converts the given string into a valid key code (Ex. "backspace" would equal 8) */
    int ToKeyCode( const std::string &key ) const;

    /** Convert the given string into a valid Joystick Button */
    int JoystickToKeyCode( std::string &key ) const;

    /** Convert the given key code to a string */
    std::string JoystickToString( int key ) const;

    /** Returns the shift value of the key (Ex. SDLK_A would return 'A') */
    char GetShiftValue( int key ) const;

public:
    virtual ~KeyConverter(void);
};


/**
================================
Converts Mouse codes to strings and vice versa
================================
*/
class MouseConverter
{
public: 
    MouseConverter(){};

    /** Convert a mouse button to a string */
    std::string ToString( int keyCode ) const;

    /** Convert a string to a key code */
    int ToKeyCode( const std::string &key ) const;

public:
    virtual ~MouseConverter(void) {};
};